#include "app_bluetooth.h"
#include <unistd.h>
#include <string.h>

static char read_buf[128];
static int buf_len = 0;
static unsigned char fixed_header[] = {0xF1, 0xDD};

static int app_bluetooth_waitACK(SerialDevice *serial_device)
{
    char ack[4];
    usleep(50000);
    int result = read(serial_device->super.fd, ack, 4);
    if (result != 4)
    {
        return -1;
    }
    if (ack[0] == 'O' && ack[1] == 'K')
    {
        return 0;
    }
    return -1;
}

// 将read_buf前n字节抛弃
static void app_bluetooth_ignore(int n)
{
    if (n == 0)
    {
        return;
    }

    buf_len -= n;
    memmove(read_buf, read_buf + n, buf_len);
}

int app_bluetooth_stat(SerialDevice *serial_device)
{
    int result = write(serial_device->super.fd, "AT\r\n", 4);
    if (result != 4)
    {
        return -1;
    }
    return app_bluetooth_waitACK(serial_device);
}

int app_bluetooth_setBaudRate(SerialDevice *serial_device, BT_BaudRate baud_rate)
{
    char buf[] = "AT+BAUD1\r\n";
    buf[7] = baud_rate;
    int result = write(serial_device->super.fd, buf, 10);
    if (result != 10)
    {
        return -1;
    }

    return app_bluetooth_waitACK(serial_device);
}

int app_bluetooth_reset(SerialDevice *serial_device)
{
    int result = write(serial_device->super.fd, "AT+RESET\r\n", 10);
    if (result != 10)
    {
        return -1;
    }

    return app_bluetooth_waitACK(serial_device);
}

int app_bluetooth_setNetID(SerialDevice *serial_device, char *net_id)
{
    if (strlen(net_id) != 4)
    {
        return -1;
    }
    char buf[] = "AT+NETID0000\r\n";
    memcpy(buf + 8, net_id, 4);
    if (write(serial_device->super.fd, buf, 14) != 14)
    {
        return -1;
    }
    return app_bluetooth_waitACK(serial_device);
}

int app_bluetooth_setMAddr(SerialDevice *serial_device, char *m_addr)
{
    if (strlen(m_addr) != 4)
    {
        return -1;
    }
    char buf[] = "AT+MADDR0000\r\n";
    memcpy(buf + 8, m_addr, 4);
    if (write(serial_device->super.fd, buf, 14) != 14)
    {
        return -1;
    }
    return app_bluetooth_waitACK(serial_device);
}

int app_bluetooth_setConnectionType(SerialDevice *serial_device)
{
    app_serial_setBlockMode(serial_device, 0);
    app_serial_setBaudRate(serial_device, BaudRate_9600);
    app_serial_flush(serial_device);
    // 检查蓝牙芯片是否能够通信
    if (app_bluetooth_stat(serial_device) == 0)
    {
        if (app_bluetooth_setBaudRate(serial_device, BT_BaudRate_115200) < 0)
            return -1;
        if (app_bluetooth_setNetID(serial_device, "1111") < 0)
            return -1;
        if (app_bluetooth_setMAddr(serial_device, "0001") < 0)
            return -1;
        if (app_bluetooth_reset(serial_device) < 0)
            return -1;
    }
    app_serial_setBaudRate(serial_device, BaudRate_115200);
    app_serial_flush(serial_device);
    int result = app_bluetooth_stat(serial_device);
    app_serial_setBlockMode(serial_device, 1);
    serial_device->super.connection_type = CONNECTION_BT;
    serial_device->super.vptr->pre_write = app_bluetooth_preWrite;
    serial_device->super.vptr->post_read = app_bluetooth_postRead;

    return result;
}

int app_bluetooth_preWrite(Device *device, void *data, int len)
{
    char buf[128];
    int id_len = 0;
    int msg_len = 0;
    memcpy(&id_len, data + 1, 1);
    memcpy(&msg_len, data + 2, 1);
    if (id_len != 2)
    {
        return -1;
    }

    memcpy(buf, "AT+MESH", 8);
    memcpy(buf + 8, data + 3, 2);
    memcpy(buf + 10, data + 5, msg_len);
    memcpy(buf + 10 + msg_len, "\r\n", 2);
    len = 12 + msg_len;
    memcpy(data, buf, len);
    return len;
}

int app_bluetooth_postRead(Device *device, void *data, int len)
{
    memcpy(read_buf + buf_len, data, len);
    buf_len += len;

    // 数据帧不全
    if (buf_len < 4)
    {
        return 0;
    }

    int data_type = 0;
    // 分辨数据帧
    for (int i = 0; i < buf_len - 3; i++)
    {
        if (memcmp(read_buf + i, "OK\r\n", 4) == 0)
        {
            // 处理收到ACK逻辑
            app_bluetooth_ignore(i + 4);
            return 0;
        }
        else if (memcmp(read_buf + i, fixed_header, 2) == 0)
        {
            // 抛弃前i字节
            app_bluetooth_ignore(i);
            data_type = 1;
            break;
        }
    }

    if (data_type == 0)
    {
        return 0;
    }

    // 处理收到的数据
    int temp_len = 0;
    memcpy(&temp_len, read_buf + 2, 1);
    if (buf_len < temp_len + 3)
    {
        // 缓冲区数据帧不全
        return 0;
    }

    unsigned char buf[128];
    memcpy(buf, &device->connection_type, 1);
    buf[1] = 2;
    buf[2] = temp_len - 4;
    memcpy(buf + 3, read_buf + 3, 2);
    memcpy(buf + 5, read_buf + 7, buf[2]);
    len = temp_len + 1;
    memcpy(data, buf, len);
    app_bluetooth_ignore(temp_len + 3);

    return len;
}
